package meteocal.boundary;
 
import java.io.Serializable;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.inject.Named;
import javax.faces.view.ViewScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.inject.Inject;
import meteocal.control.EventControl;
import meteocal.control.UserControl;
import meteocal.entity.Event;
import meteocal.entity.Users;
import meteocal.entityManager.EventManager;
import meteocal.entityManager.UserManager;
import meteocal.exception.EmptyFieldException;
import meteocal.exception.InvalidDateException;
import meteocal.exception.InvalidOperationException;
 
import org.primefaces.event.SelectEvent;
import org.primefaces.model.DefaultScheduleModel;
import org.primefaces.model.ScheduleModel;
 
@Named
@ViewScoped
public class CalendarBean implements Serializable {
    
    @Inject
    UserManager um;
    
    @Inject
    EventControl ec;
    
    @Inject
    UserControl uc;
    
    @Inject
    EventManager em;
     
    

    private ScheduleModel eventModel;
 
    private MyScheduleEvent event;
    
    private boolean deletable;
    
    private Users loggedUser;
    
    private Users modifyUser;
    
    private Date modifyBirthday;
  
    @PostConstruct
    public void init() {
        this.loggedUser = um.getLoggedUser();
        
        if(modifyUser== null){
            this.modifyUser = this.loggedUser;
        }
        if(this.loggedUser.getBirthday()!= null){
            this.modifyBirthday = this.loggedUser.getBirthday().getTime();
        }
        deletable = false;
        event = new MyScheduleEvent();
        eventModel = new DefaultScheduleModel();
        List <Event> calendar =  uc.loadCalendar();
        for(Event ev: calendar){
            Date start = ev.getStartTime().getTime();
            Date end = ev.getEndTime().getTime();
            if(ev.getCreator().equals(this.loggedUser)){
                    eventModel.addEvent(new MyScheduleEvent(ev.getId(),ev.getCreator().getEmail(),ev.getTitle(),ev.getPlace(),start,end,ev.isVisible(),true, ev.getBadWeather(),ev.isOutdoor())); //AGGIUNGERE LISTA DEGLI INVITATI PER MOSTRARE INVITATI A EVENTO
            }else{
                    eventModel.addEvent(new MyScheduleEvent(ev.getId(),ev.getCreator().getEmail(),ev.getTitle(),ev.getPlace(),start,end,ev.isVisible(),false, null,ev.isOutdoor())); //AGGIUNGERE LISTA DEGLI INVITATI PER MOSTRARE INVITATI A EVENTO
            }
        } 
        
    }
     
    public Date getInitialDate() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(calendar.get(Calendar.YEAR), Calendar.FEBRUARY, calendar.get(Calendar.DATE), 0, 0, 0);
         
        return calendar.getTime();
    } 
     
    public ScheduleModel getEventModel() {
        return eventModel;
    }
     
 
    private Calendar today() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DATE), 0, 0, 0);
 
        return calendar;
    }
     
    public MyScheduleEvent getEvent() {
        return this.event;
    }
 
    public void setEvent(MyScheduleEvent event) {
        this.event = event;
    }
     
    public void addEvent(ActionEvent actionEvent){
        
        
        
        if(event.getIdLong() == null){
            
            Event eventdb = new Event();
            eventdb.setCreator(this.loggedUser);
            Calendar start = Calendar.getInstance();
            Calendar end = Calendar.getInstance();
            start.setTime(event.getStartDate());
            end.setTime(event.getEndDate());
            
            eventdb.setStartTime(start);
            eventdb.setEndTime(end);
            eventdb.setPlace(event.getPlace());
            eventdb.setTitle(event.getTitle());
            eventdb.setVisible(event.isVisible());
            eventdb.setBadWeather(event.getBadWeather());
            eventdb.setOutdoor(event.isOutdoor());
            
            try {
                ec.createEvent(eventdb);
                ec.inviteUsers(event.getInvitedMail(), eventdb);
                this.init();
            } catch (InvalidDateException ex) {
                FacesMessage message = new FacesMessage(FacesMessage.FACES_MESSAGES, "Error: Invalid Date");
                addMessage(message); 
            } catch (EmptyFieldException ex) {
                FacesMessage message = new FacesMessage(FacesMessage.FACES_MESSAGES, "Error: Empty Field");
         
                addMessage(message);
            }
                
            
        }else{
            Event oldEvent = em.findById(event.getIdLong());
            
            Calendar start = Calendar.getInstance();
            Calendar end = Calendar.getInstance();
            start.setTime(event.getStartDate());
            end.setTime(event.getEndDate());
            
            oldEvent.setCreator(this.loggedUser);
            oldEvent.setStartTime(start);
            oldEvent.setEndTime(end);
            oldEvent.setPlace(event.getPlace());
            oldEvent.setTitle(event.getTitle());
            oldEvent.setVisible(event.isVisible());
            oldEvent.setBadWeather(event.getBadWeather());
            oldEvent.setOutdoor(event.isOutdoor());
            
            try {
                ec.editEvent(oldEvent);
                ec.inviteUsers(event.getInvitedMail(), em.findById(oldEvent.getId()));
            } catch (InvalidDateException ex) {
                FacesMessage message = new FacesMessage(FacesMessage.FACES_MESSAGES, "Error: Invalid Date");
                addMessage(message);
                
            } catch (InvalidOperationException ex) {
                Logger.getLogger(CalendarBean.class.getName()).log(Level.SEVERE, null, ex);
                FacesMessage message = new FacesMessage(FacesMessage.FACES_MESSAGES, "Error: Invalid Operation");
                addMessage(message);
            }
            
            
              
        }
         
        event = new MyScheduleEvent();
        init();
    }
     
    public void onEventSelect(SelectEvent selectEvent) {
        deletable = true;
        event = (MyScheduleEvent) selectEvent.getObject();
        
    }
    
    public void removeEvent(){
        Event ev = em.findById(this.event.getIdLong());
        ec.removeEvent(ev);
        init();
    }
    
    public void onDateSelect(SelectEvent selectEvent) {
        deletable = false;
        event = new MyScheduleEvent(null ,this.loggedUser.getEmail(), "", "", (Date) selectEvent.getObject(), (Date) selectEvent.getObject(), false,true,null,false);
    }
     
    private void addMessage(FacesMessage message) {
        FacesContext.getCurrentInstance().addMessage(null, message);
    }
    
    public String invitation(){
        return "/user/Invitation?faces-redirect=true";
    }
    
    public String notification(){
        return "/user/Notification?faces-redirect=true";
    }
    
    public String favorite(){
        return "/user/Favorite?faces-redirect=true";
    }
    
    public String home(){
        return "/user/home?faces-redirect=true";
    }

    /**
     * @return the deletable
     */
    public boolean isDeletable() {
        return deletable;
    }

    /**
     * @return the loggedUser
     */
    public Users getLoggedUser() {
        return loggedUser;
    }

    /**
     * @return the modifyUser
     */
    public Users getModifyUser() {
        return modifyUser;
    }
    
    public void convertDateToCalendar(){
        if(this.modifyBirthday != null){
        Calendar birth = Calendar.getInstance();
        birth.setTime(this.modifyBirthday);
        this.modifyUser.setBirthday(birth);
        }
    }

    /**
     * @param
     */
    public void submitModifyUser() {
        try {
            convertDateToCalendar();
            um.update(modifyUser);
            this.modifyUser = this.loggedUser;
        } catch (EmptyFieldException ex) {
            FacesMessage message = new FacesMessage(FacesMessage.FACES_MESSAGES, "Error: Empty Field");
                addMessage(message); 
        } catch (InvalidDateException ex) {
            FacesMessage message = new FacesMessage(FacesMessage.FACES_MESSAGES, "Error: Invalid Date");
                addMessage(message);
        }
    }

    /**
     * @return the modifyBirthday
     */
    public Date getModifyBirthday() {
        return modifyBirthday;
    }

    /**
     * @param modifyBirthday the modifyBirthday to set
     */
    public void setModifyBirthday(Date modifyBirthday) {
        this.modifyBirthday = modifyBirthday;
    }


}